﻿#pragma once

#include "Asset/Asset.h"
#include "Render/Texture.h"

#include <string>

class Shader : public Asset
{
public:
    explicit Shader(const std::string &path);
    ~Shader();

    void LoadFromFile(const std::string &vertPath, const std::string &fragPath);

    void Bind() const;
    void Unbind() const;
    int32_t GetUniformLocation(const std::string &location) const;
    GLuint GetID() const { return m_programID; }

    void SetInt(const std::string &name, int value) const;
    void SetUInt(const std::string &name, uint32_t value) const;
    void SetFloat(const std::string &name, float value) const;
    void SetMat4(const std::string &name, const glm::mat4 &matrix) const;
    void SetVec3(const std::string &name, const glm::vec3 &vec) const;
    void SetVec4(const std::string &name, const glm::vec4 &vec) const;
    void SetTexture(const std::string &name, const Ref<Texture> &texture, int slot = 0) const;

    Shader(const Shader &) = delete;
    Shader(Shader &) = delete;
    Shader(Shader &&) noexcept = delete;
    Shader &operator=(Shader &) = delete;
    Shader &operator=(Shader &&) noexcept = delete;

  private:
    GLuint m_programID;
    GLuint CompileShader(GLenum type, const std::string &source);
};